home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / ARGONET / PD / GRAPHICS / GIF2RPC.SPK / source / c / map16bpp < prev   
Text File  |  1995-10-08  |  2KB  |  81 lines

  1. /* map16bpp.c
  2.  * AUTHOR:      Cy Booker, cy@cheepnis.demon.co.uk
  3.  * LICENSE:     FreeWare, Copyright (c) 1995 Cy Booker
  4.  * PURPOSE:     low level 16 bit colour routines
  5.  */
  6.  
  7. #include "gif2rpc:map16bpp.h"
  8.  
  9. #include <assert.h>
  10.  
  11. #include "OS:macros.h"
  12.  
  13.  
  14.  
  15. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  16.  */
  17.  
  18. #define MINIMISE(d, v) if ((d) >= ((v)+1)) { (d) = (v); } else
  19. #define MAXIMISE(d, v) if ((d) < (v)) { (d) = (v); } else
  20.  
  21.  
  22.  
  23. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  24.  */
  25.  
  26. extern bits map_scaled_rgb_to_16bpp_colour_quick(
  27.                 rgbtupleout     *out,
  28.                 int             red,
  29.                 int             grn,
  30.                 int             blu) {
  31.   int   out_red, out_grn, out_blu;
  32.   int   colour_number;
  33.   int   t;
  34.  
  35.   t = 0xffff;                           /* helps the compiler */
  36.   MINIMISE(red, t);
  37.   MINIMISE(grn, t);
  38.   MINIMISE(blu, t);
  39.   MAXIMISE(red, 0);
  40.   MAXIMISE(grn, 0);
  41.   MAXIMISE(blu, 0);
  42.   
  43.   /*
  44.    * a first approximation is just the 5 most significant bits
  45.    * with appropriate rounding we get a better approximation at the cost of
  46.    * two ARM instruction per axis
  47.    */
  48.   out_red = ((red * 0x1f) + 0x8000) >> 16;
  49.   out_grn = ((grn * 0x1f) + 0x8000) >> 16;
  50.   out_blu = ((blu * 0x1f) + 0x8000) >> 16;
  51.  
  52.   colour_number = out_red | (out_grn << 5) | (out_blu << 10);
  53.  
  54.   if (out) {
  55.     /*
  56.      * now inline scaling of (0xffff / 0x1f)
  57.      * note that rather than |'ing shifted right 5, 10, then 15 we just do 10, then 5
  58.      *
  59.      *  %abcd e000 0000 0000
  60.      *  %abcd e000 00ab cde0
  61.      *  %abcd eabc deab cdea
  62.      */
  63.     out_red <<= 16 - 5; out_red |= out_red >> 10; out_red |= out_red >> 5;
  64.     out_grn <<= 16 - 5; out_grn |= out_grn >> 10; out_grn |= out_grn >> 5;
  65.     out_blu <<= 16 - 5; out_blu |= out_blu >> 10; out_blu |= out_blu >> 5;
  66.  
  67.     red -= out_red;
  68.     grn -= out_grn;
  69.     blu -= out_blu;
  70.     
  71.     out->colour.red = red;
  72.     out->colour.grn = grn;
  73.     out->colour.blu = blu;
  74.   }
  75.  
  76.   return colour_number;
  77. }
  78.  
  79.  
  80.  
  81.